#ifndef ODN_EVENTS_H
#define ODN_EVENTS_H

#include "ODN_DLLAccess.h"
#include "ODN_String.h"
#include "ODN_Networking.h"

namespace ouden {

//bindKeyToEvent(VC_T, C_Event_Chat::getInstance());


//Client has authority on aim direction that gets sent when firing

//Client events sent by client received by server
//Client events activate checks if is actually server acting as client and 
// doesn't call send if so

//Game event interface
class IEvent
{
public:
	//Note: Do not override this
	virtual void activate() = 0;
protected:
	//Override this to do what the event does locally
	virtual void onActivate() = 0;
};

//Base basic local only game event
class CLocalEvent : public IEvent
{
public:
	//Note: Do not override this
	virtual void activate() 		{ onActivate(); };
protected:
	//Override this to do what the event does locally
	virtual void onActivate() = 0;
};

//Networked game event interface
class INetEvent : public IEvent
{
	
public:
	
	//Note: Do not override this
	virtual void activate() = 0;
	
	//Call this when receiving the event from the network
	void activateFromPacket(Packet* pPacket) 
		{ onReceive(pPacket); onActivate(); }
	
protected:
	
	//Override this to encode the event into a packet and send it over the network
	virtual void onSend() = 0;
	
	//Override this to decode the given packet into the event's member data
	virtual void onReceive(Packet* pPacket) = 0;
	
};

class ODN_DLLACCESS C_ClientEvent : public INetEvent
{
public:
	virtual void activate();
protected:
	
	//Call this from inside onSend()
	void send(/*TODO: All sending from client parameters*/) 		{ /*TODO: Wrap client send function with parameters*/ }
	
	//Override this to do what the event does locally
	virtual void onActivate() = 0;
	
	//Override this to encode the event into a packet and send it over the network
	virtual void onSend() = 0;
	
	//Override this to decode the given packet into the event's member data
	virtual void onReceive(Packet* pPacket) = 0;
	
};

class ODN_DLLACCESS CServerEvent : public INetEvent
{
public:
	virtual void activate();
protected:
	
	//Call this from inside onSend()
	void send(/*TODO: All sending from client parameters*/) 		{ /*TODO: Wrap client send function with parameters*/ }
	
	//Override this to do what the event does locally
	virtual void onActivate() = 0;
	
	//Override this to encode the event into a packet and send it over the network
	virtual void onSend() = 0;
	
	//Override this to decode the given packet into the event's member data
	virtual void onReceive(Packet* pPacket) = 0;

};

#ifdef NOT_DEFINED_

//Bound events will be deleted automatically by the binding manager
bindKeyToEvent(VC_T, new C_Event_Chat(sMessage, iTeam) );

C_Event_Chat pEvent(sMessage, iTeam);
pEvent();

//Chat event activated at client
class C_Event_Chat : public ouden::IEvent
{
	
public:
	
	C_Event_Chat(ouden::String sMessage, unsigned char iTeam) 
	 : m_iTypeID(ID_CHAT), m_sMessage(sMessage), m_iTeam(iTeam) 		{}
	
protected:
	
	virtual void onActivate()
	{
		
		//TODO: Add message to ChatLog
		
	}
	
	virtual void onSend(/*TODO: Decide here */IClientInterface* pNetwork)
	{
		
		Bitstream bsPacket; 		//Create the packet
		bsPacket.Write(m_iTypeID); 	//Write the type identifier
		bsPacket.Write(m_iTeam); 	//Write the team identifier
		stringCompressor->EncodeString(m_sMessage.c_str(), 256, bsPacket); 	//Encode and write the message string
		
		//pNetwork->send(bsPacket, 
		
	}
	
	virtual void onReceive(Packet* pPacket)
	{
		
		
		
	}
	
private:
	
	unsigned char m_iTypeID;
	unsigned char m_iTeam; 		//0: Global message, else: Index of team message
	String m_sMessage;
	
};

class CPlayerMove_Event : public ouden::INetEvent
{
public:

	//CPlayerMove_Event();
	//virtual ~CPlayerMove_Event();
	
	/// Override this in derived game events to do what the event is supposed to do
	virtual void activate() = 0;
	
	/// Override this to return the event's type as a string
	virtual String getType() = 0;
	
	/// Override this to return a description of the event
	virtual String getDescription() = 0;
	
protected:
private:
	
	
	
};

#endif //NOT_DEFINED_

} //namespace ouden

#endif // ODN_EVENTS_H
